package sanmubird.club.v8.FunctionParam.starter;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;

public class FunctionAsParam {

    private List<Apple> inventory;

    @Before
    public void setUp() {
        inventory = new ArrayList<>();
        Apple a1 = new Apple("Green", 150d, "烟台栖霞");
        inventory.add(a1);
        Apple a2 = new Apple("Red", 200d, "陕西洛川");
        inventory.add(a2);
        Apple a3 = new Apple("Yellow", 250d, "河南灵宝");
        inventory.add(a3);
    }

    /**
     * 挑出 重量大于 150g 的苹果
     *
     * @param inventory
     * @return
     */
    public List<Apple> filterHeavyApples(List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (apple.getWeight() > 150) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * 挑出绿色的苹果
     *
     * @param inventory
     * @return
     */
    public List<Apple> filterGreenApples(List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if ("green".equals(apple.getColor())) {
                result.add(apple);
            }
        }
        return result;
    }


    /**
     * 只能适用于单一一种情况
     */
    @Test
    public void testOne() {
        List<Apple> apples = filterGreenApples(inventory);
        System.out.println(apples);
    }


    /**
     * 颜色是否为 绿色
     *
     * @param apple
     * @return
     */
    public static boolean isGreenApple(Apple apple) {
        return "green".equals(apple.getColor());
    }

    /**
     * 重量是否超过 150g
     *
     * @param apple
     * @return
     */
    public static boolean isHeavyApple(Apple apple) {
        return apple.getWeight() > 150;
    }

    private List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> applePredicate) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (applePredicate.test(apple)) {
                result.add(apple);
            }
        }
        return result;
    }

    /**
     * 采用行为参数化的思想 可以灵活应对 多变的需求
     */
    @Test
    public void testTow() {
        List<Apple> apples = filterApples(inventory, FunctionAsParam::isHeavyApple);
//        List<Apple> apples = filterApples(inventory, (Apple a) -> a.getWeight() > 150);
        System.out.println(apples);
    }


    private <T> List<T> filterElements(List<T> list, Predicate<T> predicate) {
        List<T> result = new ArrayList<>();
        for (T t : list) {
            if (predicate.test(t)) {
                result.add(t);
            }
        }
        return result;
    }

    /**
     * 使用泛型 进一步拓展
     */
    @Test
    public void testThree() {
        List<Apple> apples = filterElements(inventory, (Apple a) -> a.getWeight() > 150);
        System.out.println(apples);
    }


    @Test
    public void otherDemo() {
//        简化前
        inventory.sort(new Comparator<Apple>() {
            public int compare(Apple a1, Apple a2) {
                return a1.getWeight().compareTo(a2.getWeight());
            }
        });
//        简化后
        inventory.sort(
                (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

//        进一步简化
        inventory.sort(Comparator.comparing(Apple::getWeight));
    }

}

@Data
@AllArgsConstructor
class Apple {
    String color;
    Double weight;
    String location;
}

